#include "GRO_Button.h"


// Every child of Widget should use these in draw()
#define DRAW_PAINTER(painter)     painter.draw(area, _gui->getRenderer());
#define DRAW_BOX     painters.box.draw(area, _gui->getRenderer());
#define DRAW_FRAME   painters.frame.draw(area, _gui->getRenderer());
#define DRAW_DESIGN  painters.design.drawDesign(area, designPush, _gui->getRenderer());



namespace GRO
{


Button::Button()
        : Widget(BUTTON, Dimensions(40, 20))
        , _pressed(false)
{
    PainterMap* painterMap = getPainterMap();
    if(painterMap != NULL)
    {
        painters.box = painterMap->Default_DarkBoxPainter;
        painters.frame = painterMap->Default_ButtonUpPainter;
        
        frameDownPainter = painterMap->Default_ButtonDownPainter;
    }
    
    setChild(&text);
}
Button::Button(const Dimensions& dims)
        : Widget(BUTTON, dims)
        , _pressed(false)
{
    PainterMap* painterMap = getPainterMap();
    if(painterMap != NULL)
    {
        painters.box = painterMap->Default_DarkBoxPainter;
        painters.frame = painterMap->Default_ButtonUpPainter;
        
        frameDownPainter = painterMap->Default_ButtonDownPainter;
    }

    setChild(&text);
}
Button::Button(const Dimensions& dims, const std::string& textString)
        : Widget(BUTTON, dims)
        , _pressed(false)
        , text(textString)
{
    PainterMap* painterMap = getPainterMap();
    if(painterMap != NULL)
    {
        painters.box = painterMap->Default_DarkBoxPainter;
        painters.frame = painterMap->Default_ButtonUpPainter;
        
        frameDownPainter = painterMap->Default_ButtonDownPainter;
    }

    setChild(&text);
}

Button::~Button()
{
    
}

GRO_FramePainterID Button::getFrameDownPainter()
{
    return frameDownPainter;
}
void Button::setFrameDownPainter(GRO_FramePainterID Frame)
{
    frameDownPainter = Frame;
}
/*
void Button::applyTheme(Theme* theme, bool recursive = 0)
{
    if(theme != NULL)
    {
        for(list<ThemeItem>::iterator e = theme->items.begin(); e != theme->items.end(); ++e)
        {
            bool first = e->level & THEMEITEM_FIRST, second = e->level & THEMEITEM_SECOND
            , third = e->level & THEMEITEM_THIRD, fourth = e->level & THEMEITEM_FOURTH
            , sub1 = e->level & THEMEITEM_SUB1, sub2 = e->level & THEMEITEM_SUB2
            , sub3 = e->level & THEMEITEM_SUB3, sub4 = e->level & THEMEITEM_SUB4;
            if(e->widgetType == _type)
            {
                if(first && !(second || third || fourth) && !(sub1 || sub2 || sub3 || sub4))
                {
                    if(e->box != NULL)
                        setBox(e->box);
                    if(e->frame != NULL)
                        setFrame(e->frame);
                    if(e->design != NULL)
                        setDesign(e->design);
                }
                else if(second && !(sub1 || sub2 || sub3 || sub4))
                {
                    //if(e->box != NULL)
                        //setBoxDown(e->box);
                    if(e->frame != NULL)
                        setFrameDown(e->frame);
                    //if(e->design != NULL)
                        //setDesignDown(e->design);
                }
            }
            if(e->widgetType == TEXT)
            {
                if(text != NULL)
                    text->applyTheme(theme, recursive);
            }
        }
    }
}*/

Text& Button::getText()
{
    return text;
}

const Text& Button::getText() const
{
    return text;
}

    
bool Button::isPressed() const
{
    return _pressed;
}

void Button::setPressed(bool pressed)
{
    _pressed = pressed;
}

void Button::draw(SDL_Rect* clipRect)
{
    if(_folded || _hidden || _gui == NULL || _gui->getRenderer() == NULL)
        return;
    
    Renderer* currentRenderer = _gui->getRenderer();

    SDL_Rect area = MakeRect(pos.x, pos.y, dims.w, dims.h);

    SDL_Rect clip;
    currentRenderer->RectIntersect(*clipRect, area, clip);
    DRAW_BOX;
    
    if (text.get().size() > 0)
    {
        currentRenderer->SetClip(clip);
        text.pos.x = pos.x + dims.w/2;
        text.pos.y = pos.y + dims.h/2 - text.getHeight()/2;
        text.setGui(_gui);
        text.drawCenter(&clip);
    }
    if (_pressed)
    {
        currentRenderer->SetClip(clip);
        DRAW_PAINTER(frameDownPainter);
    }
    else
    {
        currentRenderer->SetClip(clip);
        DRAW_FRAME;
    }
    
    // Restore clip rect for widgets that embed a button
    if(clipRect != NULL)
        currentRenderer->SetClip(*clipRect);
    
    DRAW_DESIGN;
}

Widget* Button::findWidget(int mx, int my)
{
    if(_folded || _hidden || !InRect(mx, my, pos, dims))
        return NULL;
    return this;
}

std::list<Widget*> Button::getChildren()
{
    std::list<Widget*> children;
    children.push_back(&text);
    return children;
}

Widget* Button::action(PointerCursor* mouse, ActionEnum actionType)
{
    if(_folded || _hidden || mouse == NULL)
        return NULL;
    if (InRect(mouse->mx, mouse->my, pos, dims))
    {
        if(actionType == ACTION_PRESS)
        {
            _pressed = true;
            onPress.emit();
        }
        else if(actionType == ACTION_DRAG)
        {
            _pressed = true;
            onDrag.emit();
        }
        else if(actionType == ACTION_ACTIVATE)
        {
            _pressed = false;
            onClick.emit();
        }
        return this;
    }
    else if(actionType == ACTION_DRAG)
    {
        _pressed = false;
    }
    if(actionType == ACTION_ACTIVATE)
    {
        _pressed = false;
    }
    return NULL;
}

Widget* Button::action(NavCursor* nav, ActionEnum actionType)
{
    if(_folded || _hidden || nav == NULL)
        return NULL;
    if(actionType == ACTION_PRESS)
        _pressed = true;
    else if(actionType == ACTION_ACTIVATE)
    {
        onClick.emit();
        _pressed = false;
    }
    return this;
}

TiXmlElement* Button::save(TiXmlElement* parent)
{
    TiXmlElement* w = new TiXmlElement("Button");
    parent->LinkEndChild(w);
    
    saveWidgetAttributes(w);
    
    text.save(w);
    
    return w;
}

}


